#ifndef C0EF2A2B_DF48_4157_90E5_CF0705914135
#define C0EF2A2B_DF48_4157_90E5_CF0705914135
#pragma once

#include <iostream>
#include <stdarg.h>
#include <cstdlib>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <cstdio>

#define Info 0
#define Debug 1
#define Warnning 2
#define Error 3
#define Fatal 4

#define Screen 1
#define OneFile 2
#define Classfile 3

#define SIZE 1024

#define FILE_NAME "diary.txt"

class Log
{
public:
	Log()
	{
		printStyle = Screen;
		path = "./diary/";
	}
	std::string leveltostring(int level)
	{
		switch (level)
		{
		case Info:
			return "Info";
		case Debug:
			return "Debug";
		case Warnning:
			return "Warnning";
		case Error:
			return "Error";
		case Fatal:
			return "Fatal";
		default:
			return "None";
		}
	}
	void Enable(int method)
	{
		printStyle = method;
	}
	void changedir(const std::string& newpath)
	{
		path = newpath + '/';
	}
	// void logmsg(int level, const char *format, ...)
	// {
	// 	time_t t = time(nullptr);
	// 	struct tm *ctime = localtime(&t);

	// 	char leftbuffer[SIZE];
	// 	snprintf(leftbuffer, sizeof(leftbuffer), "[%s][%d-%d-%d %d:%d:%d]", leveltostring(level).c_str(),
	// 			 ctime->tm_year + 1900, ctime->tm_mon + 1, ctime->tm_mday, ctime->tm_hour, ctime->tm_min, ctime->tm_sec);

	// 	char rightbuffer[SIZE];
	// 	va_list s;
	// 	va_start(s, format);
	// 	vsnprintf(rightbuffer, sizeof(rightbuffer), format, s);

	// 	char logtxt[SIZE * 2 + 1];
	// 	snprintf(logtxt, sizeof(logtxt), "%s %s\n", leftbuffer, rightbuffer);

	// 	logprint(level,logtxt);

	// 	// FILE *fp = fopen("diary.txt", "w");
	// 	// if (fp == NULL)
	// 	// {
	// 	// 	perror("fopen fail:");
	// 	// 	return;
	// 	// }

	// 	// fwrite(logtxt, sizeof(char), sizeof(logtxt), fp);

	// 	//fclose(fp);
	// 	// printf("%d-%d-%d %d:%d:%d\n",ctime->tm_year + 1900,ctime->tm_mon + 1,ctime->tm_mday,ctime->tm_hour,ctime->tm_min,ctime->tm_sec);
	// }
	void logprint(int level, const std::string &logtxt)
	{
		switch (printStyle)
		{
		case Screen:
			std::cout << logtxt << std::endl;
			break;
		case OneFile:
			printonefile(FILE_NAME, logtxt);
			break;
		case Classfile:
			printclassfile(level, logtxt);
			break;
		default:
			break;
		}
	}
	void printonefile(const std::string &filename, const std::string &logtxt)
	{
		std::string logname = path + filename;
		int fd = open(logname.c_str(), O_APPEND | O_WRONLY | O_CREAT, 0666);
		if (fd < 0)
			return;
		write(fd, logtxt.c_str(), logtxt.size());
		close(fd);
	}
	void printclassfile(int level, const std::string &logtxt)
	{
		std::string filename = FILE_NAME;
		filename += ".";
		filename += leveltostring(level);
		printonefile(filename, logtxt);
	}
	void operator()(int level, const char *format, ...)
	{
		time_t t = time(nullptr);
		struct tm *ctime = localtime(&t);

		char leftbuffer[SIZE];
		snprintf(leftbuffer, sizeof(leftbuffer), "[%s][%d-%d-%d %d:%d:%d]", leveltostring(level).c_str(),
				 ctime->tm_year + 1900, ctime->tm_mon + 1, ctime->tm_mday, ctime->tm_hour, ctime->tm_min, ctime->tm_sec);

		char rightbuffer[SIZE];
		va_list s;
		va_start(s, format);
		vsnprintf(rightbuffer, sizeof(rightbuffer), format, s);

		char logtxt[SIZE * 2 + 1];
		snprintf(logtxt, sizeof(logtxt), "%s %s\n", leftbuffer, rightbuffer);

		logprint(level, logtxt);
	}
	~Log()
	{}

private:
	int printStyle;
	std::string path; // 路径
};

// int sum(int n,...){
// 	va_list s;
// 	va_start(s,n);

// 	int sum = 0;
// 	while(n--){
// 		sum += va_arg(s,int);
// 	}
// 	return sum;
// }

#endif /* C0EF2A2B_DF48_4157_90E5_CF0705914135 */
